package com.mt.mtyx.common.utils;

import com.mt.mtyx.entity.acl.Permission;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author WMT
 * @Date 2023/7/17 16:56
 */
public class Tree {

    /**
     * 构建菜单树形结构
     * 
     * @param all 所有源数据
     * @return 树形结构
     */
    public static List<Permission> buildTree(List<Permission> all) {
        // 1.检查菜单列表是否为空
        if (all == null || all.isEmpty()) {
            return null;
        }

        // 2.将菜单列表转换为以父菜单ID为键、子菜单列表为值的Map数据结构
        Map<Long, List<Permission>> map = all
                .stream()
                .collect(Collectors.groupingBy(Permission::getPid));

        // 3.构建菜单树
        return buildTreeRecursively(0L, 1, map);
    }

    /**
     * 递归构建子菜单的树形结构
     *
     * @param parentId 父级id
     * @param level 层级
     * @param map 父菜单ID为键、子菜单列表为值的Map数据结构
     * @return 子菜单的树形结构
     */
    private static List<Permission> buildTreeRecursively(Long parentId, int level, Map<Long, List<Permission>> map) {
        // 1.根据父菜单ID获取子菜单列表
        List<Permission> children = map.get(parentId);

        // 2.如果子菜单列表为空，则返回空列表
        if (children == null) {
            return Collections.emptyList();
        }

        // 3.用于存储构建好的菜单树
        List<Permission> tree = new ArrayList<>();

        // 4.递归遍历所有的子菜单
        for (Permission child : children) {
            // 设置子菜单的层级
            child.setLevel(level);
            // 递归构建子菜单的子菜单树
            child.setChildren(buildTreeRecursively(child.getId(), level + 1, map));
            // 将子菜单添加到菜单树中
            tree.add(child);
        }

        return tree;
    }
}
